import BMF from 'browser-md5-file';
//文件处理
export default class FlieDispose {
    constructor(fileSlicingObjectFactory) {
        //保存工厂
        this.fileSlicingObjectFactory = fileSlicingObjectFactory
    }
    async update(url, _fileSlicingFile) {
        //上传文件并返回未上传完成的碎片的md5
        let progress = await this.httpPost(url, _fileSlicingFile.flieSlice[0])
        //上传文件并判断是否上传成功
        if (progress.code === 200) {
            //设置未上传文件块md5码

            _fileSlicingFile.yetFileItemArry = progress.data
            //设置已上传的数量
            _fileSlicingFile.oldSliceNum = 0
            //判断是否有未上传文件
            if (_fileSlicingFile.yetFileItemArry.length !== 0) {

                for (let index = 1; index < _fileSlicingFile.flieSlice.length; index++) {

                    //只在没有未上传的块的时候才执行此方法
                    for (let yetFileItemArryIndex = 0; yetFileItemArryIndex < _fileSlicingFile.yetFileItemArry.length; yetFileItemArryIndex++) {

                        //查询未上传文件并上传
                        if (_fileSlicingFile.flieSlice[index].get('md5') === _fileSlicingFile.yetFileItemArry[yetFileItemArryIndex]) {

                            //判断是否暂停
                            if (_fileSlicingFile.httpState) {
                                let progress = await this.httpPost(url, _fileSlicingFile.flieSlice[index])
                                if (progress.code === 200) {
                                    let asdas = "12"

                                    _fileSlicingFile.setItem(
                                        {
                                            oldSliceNum: _fileSlicingFile.oldSliceNum + 1,
                                            progress: ((yetFileItemArryIndex + (_fileSlicingFile.flieSlice.length - _fileSlicingFile.yetFileItemArry.length) + 1) * (100 / _fileSlicingFile.flieSlice.length)).toFixed(0)

                                        })

                                }
                            } else {
                                return new Error('已暂停上传')
                            }
                        }
                    }

                }


            }
        } else if (progress.code === 201) {
            _fileSlicingFile.remove(_fileSlicingFile.oldSliceNum)
            alert("此文件已经上传过！")
            return false
        } else {
            alert("服务器出现错误！")
            return false
        }
    }
    //文件切片并返回数组
    async flieSlice(file, num) {
        let fileItemSize = Math.ceil(file.size / num);
        //获取MD
        let md5 = await this.calculate(file);
        let fileItemArry = []
        let fileItemMd5Arry = []
        for (let index = 1; index < num + 1; index++) {
            var fileItem = file.slice((fileItemSize * (index - 1)), (fileItemSize * (index)));
            let fileItemMd5Item = await this.calculate(new window.File([fileItem], 'calculate' + index, { type: file.type }));
            fileItemMd5Arry.push(fileItemMd5Item);
            let formdata = new FormData()
            formdata.append('content', fileItem)
            formdata.append('fileName', file.name)
            formdata.append('id', md5)
            formdata.append('index', index)
            formdata.append('length', num)
            formdata.append('md5', fileItemMd5Item)
            fileItemArry.push(formdata)
        }
        for (let index = 0; index < fileItemArry.length; index++) {
            fileItemArry[index].append('list', fileItemMd5Arry)
        }
        return fileItemArry
    }

    //获取md5
    calculate(file) {
        return new Promise((resolved, rejected) => {
            // var fileReader = new FileReader(),
            //     blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice,
            //     chunkSize = 2097152,
            //     // read in chunks of 2MB  
            //     chunks = Math.ceil(file.size / chunkSize),
            //     currentChunk = 0,
            //     spark = new SparkMD5();
            // fileReader.onload = function (e) {
            //     spark.appendBinary(e.target.result); // append binary string  
            //     currentChunk++;

            //     if (currentChunk < chunks) {
            //         loadNext();
            //     }
            //     else {
            //         resolved(spark.end())
            //     }
            // };
            // function loadNext() {
            //     var start = currentChunk * chunkSize,
            //         end = start + chunkSize >= file.size ? file.size : start + chunkSize;

            //     fileReader.readAsBinaryString(blobSlice.call(file, start, end));
            // };

            // loadNext();
            let bmf = new BMF()
            bmf.md5(
                file,
                (err, md5) => {
                    console.log('err:', err);
                    console.log('md5 string:', md5); // 97027eb624f85892c69c4bcec8ab0f11
                    resolved(md5)
                },
                progress => {
                    console.log('progress number:', progress);
                },
            );
        })


    }


    httpPost(url, body, Header, requestHeader) {

        return new Promise((resolved, rejected) => {
            var httpRequest = new XMLHttpRequest();//第一步：建立所需的对象
            httpRequest.open('POST', url, true);//第二步：打开连接  将请求参数写在url中
            httpRequest.timeout = 5000;
            Header ? httpRequest.setRequestHeader("Content-type", "application/json;charset=utf-8") : ''
            requestHeader ? httpRequest.responseType = requestHeader : ''
            httpRequest.send(body)
            httpRequest.onload = function () {
                if (httpRequest.status === 200) {
                    resolved(requestHeader ? httpRequest.response : JSON.parse(httpRequest.responseText))
                } else {
                    rejected(false)
                }
            }
            httpRequest.ontimeout = function (e) {
                alert('网络出现错误！')
                resolved(false)
            };
        })
    }
    //生成文件
    downloadFile(data, fileName) {
        if (!!window.ActiveXObject || 'ActiveXObject' in window) {
            let url = window.navigator.msSaveOrOpenBlob(new Blob(data), fileName)
        } else {
            let url = window.URL.createObjectURL(new Blob(data))
            let link = document.createElement('a')
            link.style.display = 'none'
            link.href = url
            link.setAttribute('download', fileName)
            document.body.appendChild(link)
            link.click()
            link.remove()
        }
    }

    /**
     * 下载文件
     */
    async  bottomHttp(url, urlFileInfo, md5, name) {
        if (!md5) {
            alert('请输入md5')
            return false
        }
        if (!name) {
            alert('请输入文件名')
            return false
        }

        let flieinfo = await this.httpPost(urlFileInfo, md5)

        if (flieinfo.code === 200) {
            flieinfo = flieinfo.data
        } else {
            alert('服务器出现错误！')
        }
        let flieinfoArry = flieinfo
        //切片请求判断是否支持大文件缓存
        if ("indexedDB" in window) {
            let httpPostArry = []
            for (let index = 1; index < flieinfoArry.length; index++) {
                let dataBase = this.fileSlicingObjectFactory.createObject('Indexdb',[md5])
                
                let httpPostArryItem = await dataBase.getObject(flieinfoArry[index]['md5'])
                if (httpPostArryItem) {
                    httpPostArryItem = httpPostArryItem.file
                } else {
                    httpPostArryItem = await this.httpPost(url, flieinfoArry[index]['md5'], true, 'blob')
                    let dataBase = this.fileSlicingObjectFactory.createObject('Indexdb',[md5])
                    dataBase.addObject({ md5: flieinfoArry[index]['md5'], file: httpPostArryItem })
                }
                httpPostArry.push(httpPostArryItem)
            }
            let dataBase = this.fileSlicingObjectFactory.createObject('Indexdb',[md5])

            this.downloadFile(httpPostArry, name)
            //测试环境。正式环境请打开此代码
            //dataBase.removeObject()
        } else {
            indexedDBOf ? alert('您的浏览器不支持断点下载，大文件请注意下载进度！') : ''
            indexedDBOf = false
            let httpPostArry = []
            for (let index = 1; index < flieinfoArry.length; index++) {
                httpPostArry.push(this.httpPost(url, flieinfoArry[index]['md5'], true, 'blob'))
                console.log(flieinfoArry[index][md5])
            }
            Promise.all(httpPostArry).then(res => {
                this.downloadFile(res, name)
            })

        }
    };


}


